package ru.amse.baltijsky.javascheme;

import ru.amse.baltijsky.javascheme.frames.image.ImageFrame;
import ru.amse.baltijsky.javascheme.frames.main.MainFrame;
import ru.amse.baltijsky.javascheme.io.IExporterManager;
import ru.amse.baltijsky.javascheme.io.importer.IImporter;
import ru.amse.baltijsky.javascheme.io.exporter.image.IImageExporterFactory;
import ru.amse.baltijsky.javascheme.io.exporter.image.IImageExporter;
import ru.amse.baltijsky.javascheme.io.exporter.stream.IStreamExporter;
import ru.amse.baltijsky.javascheme.tree.SchemaNode;
import ru.amse.baltijsky.javascheme.tree.SchemaTree;
import ru.amse.baltijsky.javascheme.tree.walker.DepthFirstTreeWalker;
import ru.amse.baltijsky.javascheme.util.Util;

import java.io.*;

/**
 * Exporter manager implementation.
 */
public class ExporterManagerImpl implements IExporterManager {
    /**
     * The destination of the export process.
     */
    private String exporterDestination;

    /**
     * Creates a new exporter manager implementation for the specified exporter destination.
     *
     * @param theExporterDest the exporter destination
     */
    public ExporterManagerImpl(String theExporterDest) {
        exporterDestination = theExporterDest;
    }

    public void applyExporter(IImporter importer, Reader in, String className, String methodName, IStreamExporter exporter) throws IOException {
        // create stream and export there
        PrintWriter out = null;
        try {
            if (exporterDestination.equals("")) {
                out = new PrintWriter(System.out);
            } else {
                out = new PrintWriter(new FileWriter(exporterDestination));
            }
            SchemaTree tree = importer.loadTree(in, className, methodName);
            exporter.export(out, new DepthFirstTreeWalker<SchemaNode>(tree.getRoot()));
        } catch (IOException e) {
            throw new IOException("import error: " + e.getMessage(), e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }

    public void applyExporter(IImporter importer, Reader in, String className, String methodName, IImageExporterFactory f) throws IOException {
        SchemaTree tree = importer.loadTree(in, className, methodName);
        // create a gui app and give the exporter to the frame
        ImageFrame.runFrame(f.createExporter(tree));
    }

    public void applyExporter(IImporter importer, Reader in, IImageExporterFactory imageExporterFactory, String bunchName, boolean bunch) throws IOException {
        SchemaTree[] trees = importer.loadTrees(in);

        String destDirPath = bunchName + " images";
        File destDir = new File(destDirPath);
        destDir.mkdirs();
        for(File f : destDir.listFiles()) {
            f.delete();
        }
        String fileNameFmt = "%s%0" + Integer.toString(Util.nDigits(trees.length)) + "d%s";
        IImageExporter exporter;
        for (int i = 0; i < trees.length; ++i) {
            System.out.print("writing test scheme " + i + " ...");
            exporter = imageExporterFactory.createExporter(trees[i]);
            try {
                File f = new File(String.format(fileNameFmt, destDirPath + File.separator + "scheme ", i, ".jpg"));
                f.createNewFile();
                exporter.exportToFile(f);
            } catch (IOException e) {
                System.out.println("Couldn't export scheme to jpg: " + e.getMessage());
            }

            Writer writer = null;
            try {
                writer = new BufferedWriter(new FileWriter(String.format(fileNameFmt, destDirPath + File.separator + "scheme ", i, ".description")));
                writer.write(exporter.getDescription());
            } catch (IOException exception) {
                System.out.println("Couldn't write scheme description");
            } finally {
                try {
                    if (writer != null)
                        writer.close();
                } catch (IOException e) {
                    // nothing
                }
            }
            System.out.println(" done");
        }
    }

    public void applyExporter(IImporter importer) {
        MainFrame.runFrame();
    }

    public void applyExporter(IImporter importer, Reader in, String className, String methodName, IImageExporterFactory factory, String fileName) throws IOException {
        System.out.print("started exporting ... ");
        try {
            File f = new File(fileName);
            f.createNewFile();
            factory.createExporter(importer.loadTree(in, className, methodName)).exportToFile(f);
        } catch (IOException e) {
            System.out.println("Couldn't export scheme to jpg: " + e.getMessage());
        }
        System.out.println("done.");
    }
}
